#include <sstream>
#include <vector>
#include <string>
#include <iostream>
#include <chrono>
#include <future>

// 获取系统毫秒数
unsigned long GetSystemMs()
{
  auto now = std::chrono::system_clock::now(); // 获取当前时间戳
  auto now_ms = std::chrono::time_point_cast<std::chrono::milliseconds>(now); // 将时间戳转换为毫秒数
  return now_ms.time_since_epoch().count();
  //return std::chrono::system_clock::now().time_since_epoch().count()/1000000;
}

// 线程休眠，主函数中也能用
void ThreadSleepMs(uint ms)
{
    std::this_thread::sleep_for(std::chrono::milliseconds(ms));
}

// 连接字符串
std::string StrJoin(const std::vector<std::string>& strVec, std::string connector)
{
	std::stringstream ssteam;
	for (auto str : strVec) {
		ssteam << str;
		if (str != strVec.back()) ssteam << connector;
	}
	return ssteam.str();
}

// 分割字符串
std::vector<std::string> StrSplit(const std::string& str, const char pattern)
{
  std::string t;
  std::vector<std::string> ret;
  std::stringstream inStream(str);   // 读取str到字符串流中

  // 使用getline函数从字符串流中读取,遇到分隔符时停止,和从cin中读取类似
  // 注意,getline默认是可以读取空格的
  while (getline(inStream, t, pattern)) {
      ret.push_back(t);
  }
  return ret;
}

// 执行命令及带回结果
uint ExecuteShell(std::string cmdStr, std::string& outStr)
{
	cmdStr += " 2>&1"; // 将错误信息也输出到终端
	FILE* pipeCmd = popen(cmdStr.c_str(), "r"); // 开启管道
	if (pipeCmd == nullptr) {
		std::cout << "popen failed!" << std::endl;
		return 0;
	}

	outStr = "";
	char outBuf[1000];
	while (fgets(outBuf, sizeof(outBuf), pipeCmd) != NULL) {
		outStr += outBuf;
		std::cout << " :" << outBuf;
	}
	pclose(pipeCmd); // 关闭管道
	return outStr.length();
}

// 转换字符串为整型，不抛异常
long StrToLongInt(const std::string& str, long def = 0)
{
  char* end = nullptr;
  long int result = std::strtol(str.c_str(), &end, 10);
  if (end == str.c_str() + str.size()) {
    // 字符串转换完毕，没有剩余字符
    return static_cast<int>(result);
  } else {
    // 字符串中有非数字字符，返回默认值或错误处理
    return def; // 或者其他错误处理
  }
}